
/*
vgWindow.cc
This file is part of opengl-vrml-assembly.
Copyright (C) Rafal Pielech, rafal.pielech@gmail.com

opengl-vrml-assembly is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

opengl-vrml-assembly is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with opengl-vrml-assembly.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <windows.h>
#include <vgWindow.h>

std::vector<vgWindow*> vgWindow::instances = std::vector<vgWindow*>(0);

LRESULT CALLBACK vgWndProc(HWND hwnd,
                           UINT msg,
                           WPARAM wParam,
                           LPARAM lParam)
{
  for(int i=0; i<vgWindow::instances.size(); i++)
  {
    if(vgWindow::instances[i]->vgForwardMessage(hwnd, msg, wParam, lParam))
    {
      return 0;
    }
  }
  return ::DefWindowProc(hwnd, msg, wParam, lParam);
}

bool vgWindow::vgForwardMessage(HWND hwnd,
                                UINT msg,
                                WPARAM wParam,
                                LPARAM lParam)
{
  bool fmResult = false;
  // Look for listener
  for(int i=0; i<listeners.size(); i++)
  {
    if(listeners[i].first == hwnd)
    {
      fmResult = true;
      listeners[i].second->vgListen(hwnd, msg, wParam, lParam);
    }
  }
  return fmResult;
}

const char vgWindow::VG_WND_CLASS_TERMINAL[VG_WND_CLASS_NAME_LENGTH] = "vg_wnd_class_terminal";
const char vgWindow::VG_WND_CLASS_INSPECTOR[VG_WND_CLASS_NAME_LENGTH] = "vg_wnd_class_inspector";

vgWindow::vgWindow(void)
{
  // Register instance
  vgWindow::instances.push_back(this);
  WNDCLASSEX wc_struct;

  ::ZeroMemory(&wc_struct, sizeof(WNDCLASSEX));
  wc_struct.cbSize        = sizeof(WNDCLASSEX);
  wc_struct.style         = 0;
  wc_struct.lpfnWndProc   = vgWndProc;
  wc_struct.cbClsExtra    = 0;
  wc_struct.cbWndExtra    = 0;
  wc_struct.hInstance     = GetModuleHandle(NULL);
  wc_struct.hIcon         = ::LoadIcon(NULL, IDI_APPLICATION);
  wc_struct.hCursor       = ::LoadCursor(NULL, IDC_ARROW);
  wc_struct.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  wc_struct.lpszMenuName  = NULL;
  wc_struct.lpszClassName = vgWindow::VG_WND_CLASS_TERMINAL;
  wc_struct.hIconSm       = ::LoadIcon(NULL, IDI_APPLICATION);

  if(!::RegisterClassEx(&wc_struct))
  {
	  return;
  }

  ::ZeroMemory(&wc_struct, sizeof(WNDCLASSEX));
  wc_struct.cbSize        = sizeof(WNDCLASSEX);
  wc_struct.style         = 0;
  wc_struct.lpfnWndProc   = vgWndProc;
  wc_struct.cbClsExtra    = 0;
  wc_struct.cbWndExtra    = 0;
  wc_struct.hInstance     = GetModuleHandle(NULL);
  wc_struct.hIcon         = ::LoadIcon(NULL, IDI_APPLICATION);
  wc_struct.hCursor       = ::LoadCursor(NULL, IDC_ARROW);
  wc_struct.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  wc_struct.lpszMenuName  = NULL;
  wc_struct.lpszClassName = vgWindow::VG_WND_CLASS_INSPECTOR;
  wc_struct.hIconSm       = ::LoadIcon(NULL, IDI_APPLICATION);

  if(!::RegisterClassEx(&wc_struct))
  {
    ::UnregisterClass(vgWindow::VG_WND_CLASS_TERMINAL, GetModuleHandle(NULL));
  }
}

bool vgWindow::vgRegisterListener(HWND hwnd, vgMessageListener* ml)
{
  listeners.push_back(std::make_pair(hwnd, ml));
  return true;
}

vgWindow::~vgWindow(void)
{
  ::UnregisterClass(vgWindow::VG_WND_CLASS_TERMINAL, GetModuleHandle(NULL));
  ::UnregisterClass(vgWindow::VG_WND_CLASS_INSPECTOR, GetModuleHandle(NULL));
}
